#!/usr/bin/python

import time
import sys

def clear_terminal():
    sys.stderr.write("\x1b[2J\x1b[H")

def read_interrupt_infos():
    file_info = open("/proc/interrupts").read().split("\n")
    cpus = file_info.pop(0).split()
    fields_count = len(cpus) + 3
    
    int_infos = {}
    for info in file_info:
        if len(info) < 1:
            continue
        fields = info.split()
        irq = fields[0].strip(":")
        ints = [int(n) for n in fields[1:len(cpus)]]
        if len(ints) < len(cpus):
            ints.extend([0] * (len(cpus) - len(ints)))

        fields = fields[1 + len(cpus):]
        if len(fields) < 2:
            fields.extend([""] * (2 - len(fields)))
        comment = fields[0]
        dev_name = " ".join(fields[1:])
        
        int_infos[irq] = (ints, comment, dev_name)
    return cpus, int_infos

def print_items(print_info):
    max_field_sizes = []
    for i in range(0, len(print_info[0])):
        max_field_sizes.append(max([len(item[i]) for item in print_info]))
    
    for item in print_info:
        for i, field in enumerate(item):
            sys.stdout.write(field.ljust(max_field_sizes[i]) + "  ")
        print
        
def itop():
    cpus, last_int_infos = read_interrupt_infos()
    print "Wait 1 second to count difference..."
    
    while True:
        cur_int_infos = read_interrupt_infos()[1]
        int_infos = []
        for irq, (cur_ints, comment, dev) in cur_int_infos.iteritems():
            last_int_info = last_int_infos.get(irq)
            if not last_int_info:
                continue
            last_ints = last_int_info[0]
            
            int_diffs = [cur_ints[i] - last_int for i, last_int in enumerate(last_ints)]
            int_infos.append((irq, cur_ints, int_diffs, comment, dev))
            
        int_infos.sort(key=lambda item: sum(item[2]), reverse=True)
        
        print_info = []
        
        head = []
        head.extend(["IRQs/Second", "IRQs TOTAL"])
        head.extend(cpus)
        head.append("(IRQ) Device")
        print_info.append(head)
        
        for irq, cur_ints, int_diffs, comment, dev in int_infos:
            item = []
            item.extend([str(sum(int_diffs)), str(sum(cur_ints))])
            item.extend([str(int_diff) for int_diff in int_diffs])
            item.append("(%s) %s %s " % (irq.ljust(3), comment, dev))
            print_info.append(item)
            
        clear_terminal()
        print_items(print_info)
        time.sleep(1)
        last_int_infos = cur_int_infos
        
if __name__ == '__main__':
    try:
        itop()
    except KeyboardInterrupt:
        print


